home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 February
/
EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso
/
earcd
/
comm2
/
xbtx.lha
/
Source
/
ModemService.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1995-12-03
|
9KB
|
474 lines
/*
** $Id: ModemService.cpp 1.6 1995/12/03 12:16:23 olsen Exp olsen $
**
** :ts=4
*/
/*
* Copyright © 1995 by Olaf Barthel, All Rights Reserved
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software has not been validated by the ``Bundesamt fuer Zulassungen in
* der Telekommunikation'' of the ``Deutsche Bundepost Telekom'' and thus
* must not be used for accessing the BTX-Network of the Telekom in Germany.
*
* Diese Software hat keine Zulassung durch das Bundesamt fuer Zulassungen in
* der Telekommunikation der Deutschen Bundespost Telekom und darf daher nicht
* am Netz der Deutschen Bundespost Telekom in Deutschland betrieben werden.
*/
/****************************************************************************/
#include <dos/dos.h>
#include <devices/timer.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#ifdef __SASC
#include <pragmas/exec_pragmas.h>
#include <pragmas/dos_pragmas.h>
extern struct ExecBase *SysBase;
extern struct DosLibrary *DOSBase;
#endif // _SASC
#include <string.h>
#include <stdio.h>
/****************************************************************************/
#define D(x)
/****************************************************************************/
#ifndef _MODEMSERVICE_HPP
#include "ModemService.hpp"
#endif
/****************************************************************************/
ModemService::ModemService()
{
AppChannel = NULL;
Connected = FALSE;
HangupCommand = NULL;
TimePort = NULL;
TimeRequest = NULL;
}
ModemService::~ModemService()
{
Close();
}
LONG ModemService::Open(IOChannel *Channel,BTXDisplay *Display)
{
if(TimePort = CreateMsgPort())
{
TimeMask = 1UL << TimePort->mp_SigBit;
if(TimeRequest = (struct timerequest *)CreateIORequest(TimePort,sizeof(timerequest)))
{
if(OpenDevice((UBYTE *)TIMERNAME,UNIT_VBLANK,(struct IORequest *)TimeRequest,NULL))
{
DeleteIORequest((struct IORequest *)TimeRequest);
TimeRequest = NULL;
}
}
}
if(TimeRequest)
{
AppChannel = Channel;
AppDisplay = Display;
return(0);
}
Close();
return(-1);
}
VOID ModemService::Close(VOID)
{
if(Connected)
Disconnect();
if(TimeRequest)
{
CloseDevice((struct IORequest *)TimeRequest);
DeleteIORequest((struct IORequest *)TimeRequest);
TimeRequest = NULL;
}
if(TimePort)
{
DeleteMsgPort(TimePort);
TimePort = NULL;
}
if(HangupCommand)
{
delete HangupCommand;
HangupCommand = NULL;
}
AppChannel = NULL;
}
LONG ModemService::Connect(CONST STRPTR Init,CONST STRPTR Dial,CONST STRPTR Number,CONST STRPTR Hangup,LONG Timeout)
{
STATIC STRPTR ResponseTable[] =
{
"OK",
"NO CARRIER",
"ERROR",
"BUSY",
"NO DIALTONE",
"CONNECT",
"NO ANSWER",
"RINGING",
"RING",
NULL
};
char Buffer[40];
LONG Result,i;
ULONG Signals;
AppDisplay->PutLine(NULL);
if(!HangupCommand)
{
if(HangupCommand = new char[strlen(Hangup) + 1])
strcpy(HangupCommand,Hangup);
}
SetSignal(0,TimeMask);
TimeRequest->tr_node.io_Command = TR_ADDREQUEST;
TimeRequest->tr_time.tv_secs = Timeout;
TimeRequest->tr_time.tv_micro = 0;
SendIO((struct IORequest *)TimeRequest);
D(printf("timeout = %ld\n",Timeout));
if(Init[0])
{
BOOL Done = FALSE;
SendCommand(Init);
do
{
Signals = Wait(AppChannel->WaitMask() | AppDisplay->WaitMask() | SIGBREAKF_CTRL_C | TimeMask);
if(Signals & SIGBREAKF_CTRL_C)
{
AppDisplay->PutLine("Aborted");
if(!CheckIO((struct IORequest *)TimeRequest))
AbortIO((struct IORequest *)TimeRequest);
WaitIO((struct IORequest *)TimeRequest);
return(MODEM_NoCarrier);
}
if(Signals & AppDisplay->WaitMask())
{
Result = AppDisplay->GetChar();
if(Result == '\033' || Result == ('C' & 0x1F))
{
AppDisplay->PutLine("Aborted");
if(!CheckIO((struct IORequest *)TimeRequest))
AbortIO((struct IORequest *)TimeRequest);
WaitIO((struct IORequest *)TimeRequest);
return(MODEM_NoCarrier);
}
}
if(Signals & AppChannel->WaitMask())
{
Result = GetLine(Buffer,40);
D(printf("result %ld buffer |%s|\n",Result,Buffer));
if(Result > 0)
{
AppDisplay->PutLine(Buffer);
for(i = 0 ; ResponseTable[i] ; i++)
{
if(strstr(Buffer,ResponseTable[i]))
{
if(i == MODEM_Ok)
Done = TRUE;
else
{
AppDisplay->PutLine("Error while initializing modem");
if(!CheckIO((struct IORequest *)TimeRequest))
AbortIO((struct IORequest *)TimeRequest);
WaitIO((struct IORequest *)TimeRequest);
return(i);
}
}
}
}
}
if(Signals & TimeMask)
{
WaitIO((struct IORequest *)TimeRequest);
if(Done)
{
TimeRequest->tr_node.io_Command = TR_ADDREQUEST;
TimeRequest->tr_time.tv_secs = Timeout;
TimeRequest->tr_time.tv_micro = 0;
SendIO((struct IORequest *)TimeRequest);
}
else
{
AppDisplay->PutLine("Timeout while initializing modem");
return(MODEM_Timeout);
}
}
}
while(!Done);
}
SendCommand(Dial);
SendCommand(Number);
SendCommand("^M");
for(;;)
{
Signals = Wait(AppChannel->WaitMask() | AppDisplay->WaitMask() | TimeMask | SIGBREAKF_CTRL_C);
if(Signals & SIGBREAKF_CTRL_C)
{
AppDisplay->PutLine("Aborted");
if(!CheckIO((struct IORequest *)TimeRequest))
AbortIO((struct IORequest *)TimeRequest);
WaitIO((struct IORequest *)TimeRequest);
SendCommand("^M");
return(MODEM_NoCarrier);
}
if(Signals & AppDisplay->WaitMask())
{
LONG Result = AppDisplay->GetChar();
if(Result == '\033' || Result == ('C' & 0x1F))
{
AppDisplay->PutLine("Aborted");
if(!CheckIO((struct IORequest *)TimeRequest))
AbortIO((struct IORequest *)TimeRequest);
WaitIO((struct IORequest *)TimeRequest);
SendCommand("^M");
return(MODEM_NoCarrier);
}
}
if(Signals & AppChannel->WaitMask())
{
Result = GetLine(Buffer,40);
if(Result > 0)
{
AppDisplay->PutLine(Buffer);
for(i = 0 ; ResponseTable[i] ; i++)
{
if(strstr(Buffer,ResponseTable[i]))
{
AppChannel->Flush();
if(!CheckIO((struct IORequest *)TimeRequest))
AbortIO((struct IORequest *)TimeRequest);
WaitIO((struct IORequest *)TimeRequest);
if(i == MODEM_Connect)
{
Connected = TRUE;
return(i);
}
if(i != MODEM_Ringing && i != MODEM_Ring)
{
D(printf("i %ld MODEM_Ringing %ld MODEM_Ring %ld\n",i,MODEM_Ringing,MODEM_Ring));
AppDisplay->PutLine("Error while dialing");
return(i);
}
}
}
}
}
if(Signals & TimeMask)
{
WaitIO((struct IORequest *)TimeRequest);
AppDisplay->PutLine("Timeout while dialing");
SendCommand("^M");
return(MODEM_Timeout);
}
}
}
VOID ModemService::Disconnect(VOID)
{
if(Connected)
{
if(HangupCommand)
SendCommand(HangupCommand);
Connected = FALSE;
}
if(HangupCommand)
{
delete HangupCommand;
HangupCommand = NULL;
}
}
LONG ModemService::GetLine(STRPTR Buffer,LONG Size)
{
LONG Len = 0,Result;
for(;;)
{
Result = AppChannel->GetCharDirect(4);
if(Result < 0 || Result == '\r')
{
Buffer[Len] = 0;
return(Len);
}
else
{
if(Result == '\n' || (!Len && Result == ' '))
continue;
if(Result < ' ')
{
Result += ' ';
Buffer[Len++] = '^';
if(Len == Size - 1)
{
Buffer[Len] = 0;
return(Len);
}
}
Buffer[Len++] = (char)Result;
if(Len == Size - 1)
{
Buffer[Len] = 0;
return(Len);
}
}
}
}
VOID ModemService::SendCommand(CONST STRPTR Command)
{
BOOL Escape;
LONG i;
char c;
for(i = 0, Escape = FALSE ; i < strlen(Command) ; i++)
{
switch(Command[i])
{
case '^':
if(Escape)
AppChannel->PutCharDirect('^');
Escape ^= TRUE;
break;
case '~':
if(Escape)
AppChannel->PutCharDirect('~');
else
Delay(TICKS_PER_SECOND);
break;
default:
if(Escape)
{
c = (char)(Command[i] & 0x1F);
Escape = FALSE;
}
else
c = Command[i];
AppChannel->PutCharDirect(c);
break;
}
}
}